package com.ferryc.commons.scan;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import com.ferryc.commons.exception.BaseException;
import com.ferryc.commons.utils.BeanUtil;
import com.ferryc.commons.utils.Exceptions;
import com.ferryc.commons.utils.WebUtil;
import com.ferryc.commons.web.JsonResponse;
import com.ferryc.constant.CommonConstants;
import com.ferryc.constant.ResultConstant;

/**
 * 
 * <pre>
 * 【类型】: ExceptionResolver <br/> 
 * 【作用】: 异常处理，对ajax类型的异常返回ajax错误，避免页面问题. <br/>  
 * 【时间】：2017年5月23日 上午9:50:51 <br/> 
 * 【作者】：Ferry Chen <br/>
 * </pre>
 */
@Component
@SuppressWarnings("unchecked")
public class ExceptionResolver implements HandlerExceptionResolver {
	/**
	 * 日志对象
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	/** */
	@Autowired
	private JacksonObjectMapper jacksonObjectMapper;

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
		// log记录异常
		logger.error("ExceptionResolver:" + e.getMessage(), e);
		// 非控制器请求照成的异常
		if (!(handler instanceof HandlerMethod)) {
			return new ModelAndView("error/500");
		}
		HandlerMethod handlerMethod = (HandlerMethod) handler;

		if (WebUtil.isAjax(handlerMethod)) {
			JsonResponse result = new JsonResponse();
			result.setMsg(e.getMessage());
			if (e instanceof BaseException) {
				result.setCode(String.valueOf(((BaseException) e).getStatus()));
			} else if (e instanceof UnauthorizedException) {
				result.setMsg(ResultConstant.UN_AUTH_USER);
				result.setCode(String.valueOf(CommonConstants.EX_CLIENT_AUTH_ERROR_CODE));
			}
			MappingJackson2JsonView view = new MappingJackson2JsonView();
			view.setObjectMapper(jacksonObjectMapper);
			view.setContentType("text/html;charset=UTF-8");
			return new ModelAndView(view, BeanUtil.toMap(result));
		}
		if (e instanceof UnauthorizedException) {
			return new ModelAndView("error/500").addObject("error", ResultConstant.UN_AUTH_USER);
		}
		// 页面指定状态为500，便于上层的resion或者nginx的500页面跳转，由于error/500不适合对用户展示
		return new ModelAndView("error/500").addObject("error", Exceptions.getStackTraceAsString(e));
	}

}